const {
    Ok, OkMsg, Error, ErrMsg,
    hasOwn, isObject
} = Require("utils.libs.index");

function getUserInfo(type, value) {
    const supportTypes = {
        email: "email",
        mobile: "mobile",
        userName: "user_name" // 用户名需要模型支持
    };
    if (!supportTypes[type]) {
        throw new Exception(`Login type :${type} is not support`);
    }

    const [user] = Process("models.admin.user.get", {
        select: [
            "id",
            "name",
            "password",
            "type",
            "email",
            "mobile",
            "user_name",
            "extra",
            "status",
        ],
        wheres: [
            { column: supportTypes[type], value: value },
            { column: "status", value: "enabled" },
        ],
        limit: 1,
    });
    return user;
}

function login(payload) {
    console.log('>>>>>login', payload);
    if (hasOwn(payload, 'captcha') && isObject(payload.captcha)) {
        const captcha = Process(
            "yao.utils.CaptchaValidate",
            payload.captcha.id,
            payload.captcha.code
        );
        if (captcha !== true) {
            throw new Exception("验证码不正确!", 400);
        }
    }
    let { password, email, mobile, userName } = payload;

    let user = null;
    if (email != null) {
        user = getUserInfo("email", email);
    } else if (mobile != null) {
        user = getUserInfo("mobile", email);
    } else if (userName != null) {
        user = getUserInfo("userName", userName);
    }
    if (!user) {
        return ErrMsg("用户不存在");
    }
    try {
        const password_validate = Process(
            "utils.pwd.Verify",
            password,
            user.password
        );
        if (password_validate !== true) {
            return ErrMsg("密码不正确");
        }
    } catch (error) {
        return ErrMsg("密码不正确");
    }
    const timeout = 60 * 60 * 8;
    const sessionId = Process("utils.str.UUID"); // 生成一个随机的session id
    let userPayload = { ...user };
    delete userPayload.password; // 去掉密码字段
    const jwtOptions = {
        timeout: timeout,
        sid: sessionId,
    };
    const jwtClaims = { user_name: user.name };
    //需要注意的是在这里无法生成studio的token,因为这个处理器只接受3个参数，
    //而生成studio的token需要在第4个参数里传入secretkey
    const jwt = Process("utils.jwt.Make", user.id, jwtClaims, jwtOptions);
    Process("session.set", "user_id", user.id, timeout, sessionId);
    Process("session.set", "token", jwt.token, timeout, sessionId);
    Process("session.set", "user", userPayload, timeout, sessionId);

    // 设置权限缓存
    // const userAuthObject = getUserAuthObjects(user.id);
    // Process(
    //     "session.set",
    //     "user_auth_objects",
    //     userAuthObject,
    //     timeout,
    //     sessionId
    // );

    return Ok({
        sid: sessionId,
        userInfo: userPayload,
        // menus: Process("scripts.admin.menu_node.xgenMenu"),
        token: jwt.token,
        expires_at: jwt.expires_at,
    });
}